package br.brpv.silvestrin.vendas.mainactivity;

import android.content.*;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcelable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import br.brpv.silvestrin.vendas.R;
import br.brpv.silvestrin.vendas.domain.*;
import br.brpv.silvestrin.vendas.listeners.*;
import br.brpv.silvestrin.vendas.manager.ClientManager;
import br.brpv.silvestrin.vendas.manager.OrderManager;
import br.brpv.silvestrin.vendas.util.ShowMessage;
import br.brpv.silvestrin.vendas.webservice.ServerConnection;
import br.brpv.silvestrin.vendas.webservice.ServerDataCacheService;

import java.util.ArrayList;

//TODO Utilizar Dialog para setar a quatidade e preco do item a ser adicionado
//TODO quando muda de aba e volta, a está salvando a pesquisa dos itemcfg e colocando ela na pesquisa dos itens também
//TODO quando adicionar item no pedido, setSelectionAfterHeaderView(selected), para o usuário ver que o item foi adicionado

public class FinalConsumerFragment extends CompanyFragment implements AddedItemsListInterface, CompanyParamsDefaultQueryListener,
        OrderManager.OrderManagerInterface, FinalizeOrderInterface, ClientManager.ClientManagerInterface {


    private enum Mode {WAIT_NEW_ORDER, MAKE_ORDER, ENDING_ORDER}


    LinearLayout addItemView;
    LinearLayout finalFormView;

    private static final String SAVE_ITEMS_LIST_FC = "saveItemListFC";
    private static final String SAVE_SEARCH_OPTION_FC = "searchOptionSavedFC";
    private static final String SAVE_COD_COMPANY_FC = "saveCodCompanyFC";

    private ItemAdapter adapterItems = null;
    private AddedItemAdapter adapterAddedItem = null;

    private Mode finalConsumerMode = Mode.WAIT_NEW_ORDER;

    private CompanyParameters paramsSelectedCompany = null;
    private String finalConsumerEstablishmentID = null;
    private String finalConsumerClientID = null;

    private EstabParamsDefault finalConsumerParamsDefault;

    private Order currentOrder = null;
    private OrderManager orderManager;
    private ClientManager clientManager;
    private ArrayList<AddedItem> itemsToSend = null; //lista de itens a serem enviados utilizada para poder reenviar.

    private ServerDataCacheService mServerDataCacheBinder;
    private boolean mBound;
    AddItemsScreen addItemsScreen;
    FinalizeOrderScreen finalizeOrderScreen;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addItemsScreen = new AddItemsScreen(getActivity(), this);
        addItemsScreen.setCodSelectedCompany(codSelectedCompany);

        finalizeOrderScreen = new FinalizeOrderScreen(getActivity(), this);

        orderManager = new OrderManager(getActivity(), this);
        clientManager = new ClientManager(getActivity(), this, null);
        clientManager.setCodSelectedCompany(codSelectedCompany);

        //bind on ServerDataCacheService
        Intent intent = new Intent(getActivity(), ServerDataCacheService.class);
        getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

        /*
        if(savedInstanceState != null) {
            loadSavedItemList(savedInstanceState);
        } else if (finalConsumerMode == Mode.MAKE_ORDER) {
            ServerConnection.getItems(codSelectedCompany, this);
        }
        */
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View finalConsumerView = inflater.inflate(R.layout.final_consumer_layout, container, false);

        addItemView = (LinearLayout)finalConsumerView.findViewById(R.id.final_consumer_add_item);
        finalFormView = (LinearLayout)finalConsumerView.findViewById(R.id.final_consumer_end);

        addItemsScreen.setAddItemsView(addItemView);
        finalizeOrderScreen.setFinalFormView(finalFormView);

        Button backButton = (Button)addItemView.findViewById(R.id.add_item_back_button);
        backButton.setVisibility(View.GONE);

        if(finalConsumerMode == Mode.ENDING_ORDER) {
            addItemsScreen.setInvisible();
            finalizeOrderScreen.setVisible();
        } else {
            addItemsScreen.setVisible();
            finalizeOrderScreen.setInvisible();
        }

        return finalConsumerView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        addItemsScreen.initAddItemScreen();
        addItemsScreen.setEstablishmentName("Consumidor Final");
        finalizeOrderScreen.initFinalizeOrderScreen();

        setFinalConsumerMode(finalConsumerMode);

        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStart() {
        super.onStart();
        //this code is to fix an android bug
        if(finalizeOrderScreen != null) {
            finalizeOrderScreen.showFinalConsumerFieldsIfNeeded();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        ArrayList<Item> itemArray = new ArrayList<Item>();

        if(adapterAddedItem != null && adapterItems != null) {

            for(int i = 0; i < adapterItems.getCount(); i++) {
                itemArray.add(adapterItems.getItem(i));
            }
        }

        outState.putParcelableArrayList(SAVE_ITEMS_LIST_FC, itemArray);
        outState.putInt(SAVE_COD_COMPANY_FC, codSelectedCompany);

        super.onSaveInstanceState(outState);
    }

    public void loadSavedItemList(Bundle savedInstanceState){
        if(savedInstanceState != null) {
            ArrayList<Parcelable> savedArray = savedInstanceState.getParcelableArrayList(SAVE_ITEMS_LIST_FC);
            ArrayList<Item> itemArray = new ArrayList<Item>();

            for(Parcelable p: savedArray) {
                itemArray.add((Item) p);
            }

            codSelectedCompany = savedInstanceState.getInt(SAVE_COD_COMPANY_FC);

        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        if (mBound) {
            getActivity().unbindService(mConnection);
            mBound = false;
        }
    }

    private ServiceConnection mConnection = new ServiceConnection(){

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            ServerDataCacheService.LocalBinder localBinder = (ServerDataCacheService.LocalBinder)iBinder;

            mServerDataCacheBinder = localBinder.getService();
            addItemsScreen.setmServerDataCacheBinder(mServerDataCacheBinder);
            finalizeOrderScreen.setmServerDataCacheBinder(mServerDataCacheBinder);
            clientManager.setmServerDataCacheBinder(mServerDataCacheBinder);
            mBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            addItemsScreen.setmServerDataCacheBinder(null);
            finalizeOrderScreen.setmServerDataCacheBinder(null);
            mBound = false;
        }
    };


    @Override
    public void initializeAddingItems() {
        setFinalConsumerMode(Mode.MAKE_ORDER);
        getCompanyParams();
        finalizeOrderScreen.setCodSelectedCompany(codSelectedCompany);
    }

    @Override
    public void finalizeAddingItems(ArrayList<AddedItem> itemsAdded, String chosePriceTable) {
        itemsToSend = itemsAdded;

        currentOrder.setPriceTableId(chosePriceTable);
        finalizeOrderScreen.setOrder(currentOrder);
        setFinalConsumerMode(Mode.ENDING_ORDER);
        //orderManager.addItemsToOrder(itemsToSend);
        orderManager.getOrderValues();

        //finalizeOrderScreen.setClientID(finalConsumerClient.getClientId());
        finalizeOrderScreen.setParamsSelectedCompany(paramsSelectedCompany);
        finalizeOrderScreen.setClientAndEstablishment(paramsSelectedCompany.getCodFinalConsumer(), finalConsumerClientID, finalConsumerEstablishmentID, finalConsumerParamsDefault);
        //finalizeOrderScreen.setClientEstablishment(finalConsumerDetails);
    }



    private void getCompanyParams(){
        CompanyParameters compParams = null;

        if(mServerDataCacheBinder != null) //ve se tem na cache
            compParams =  mServerDataCacheBinder.getCompanyParams(codSelectedCompany);
        if(compParams == null) //busca no servidor caso contrario
            ServerConnection.getCompanyParamsDefault(String.valueOf(codSelectedCompany), FinalConsumerFragment.this);
        else initCompanyParams(compParams); //inicializa com o valor buscado na cache

        ArrayList<PriceTable> priceTables = null;
        if(mServerDataCacheBinder != null){
            priceTables = mServerDataCacheBinder.getCompanyPriceTable(codSelectedCompany);
        }
        if(priceTables == null || priceTables.size() == 0){
            ServerConnection.getCompanyPriceTable(codSelectedCompany, FinalConsumerFragment.this);
        } else {
            addItemsScreen.setPriceTableList(priceTables);
        }

        ArrayList<UnitOfMeasurement> unitOfMeasurements = null;
        if(mServerDataCacheBinder != null) {
            unitOfMeasurements = mServerDataCacheBinder.getUnitsOfMeasurements(codSelectedCompany);
        }
        if(unitOfMeasurements == null || unitOfMeasurements.size() == 0) {
            ServerConnection.getUnitsOfMeasurement(codSelectedCompany, FinalConsumerFragment.this);
        } else {
            addItemsScreen.setUnitsOfMeasurement(unitOfMeasurements);
        }

    }

    private void initCompanyParams(CompanyParameters params){
        if(params == null){
            setFinalConsumerMode(Mode.WAIT_NEW_ORDER);
            ShowMessage.alertDialog(getActivity(),R.string.error_missing_company_params);

        } else {
            paramsSelectedCompany = params;
            //getItemsList();
            clientManager.getClientList(); //para pegar os detalhes do cliente consumidor final
        }
    }

    private void initFinalConsumerDetails(Establishment establishment){
        finalConsumerEstablishmentID = establishment.getEstablishmentId();
        clientManager.getClientDefaultParams(establishment.getClientId(),establishment.getEstablishmentId());
        initOrder();
    }

    private void getFinalConsumerDetails(ArrayList<Client> clientsList){
        for(Client c : clientsList){
            if(c.getCodClient().equals(paramsSelectedCompany.getCodFinalConsumer())){
                finalConsumerClientID = c.getClientId();
                clientManager.getEstablishmentsList(c);
            }
        }
    }

    @Override
    public void orderInitialized(Order order) {
        currentOrder = order;
        addItemsScreen.setNewOrder(currentOrder);
    }

    @Override
    public void orderFinalized(Order order) {
        currentOrder = null;
        setFinalConsumerMode(Mode.WAIT_NEW_ORDER);
    }

    @Override
    public void orderFromSaveToFinalized(String orderId) {
    }

    @Override
    public void onValorBrutoReturn(String valorBruto) {
        finalizeOrderScreen.setValorBruto(valorBruto);
    }

    @Override
    public void onValorLiquidoReturn(String valorLiquido) {
        finalizeOrderScreen.setValorLiquido(valorLiquido);
    }

    @Override
    public void onItemsAdded(ArrayList<AddedItem> itemsSent) {
        itemsToSend = itemsSent;
    }

    @Override
    public void onItemRemoved(String itemId) {
    }

    @Override
    public void onItemAdded(AddedItem item) {
    }

    @Override
    public void orderRemoved(String resultString) {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    private void initOrder(){
        User user = mServerDataCacheBinder.getCurrentUser();

        orderManager.initOrder(user, paramsSelectedCompany, finalConsumerClientID, finalConsumerEstablishmentID);
    }

    private void setFinalConsumerMode(Mode mode){
        switch (mode) {
            case MAKE_ORDER:
                finalConsumerMode = Mode.MAKE_ORDER;
                if(addItemsScreen != null)addItemsScreen.setAddItemsMode(AddItemsScreen.Mode.MAKE_ORDER);
                if(finalizeOrderScreen != null) finalizeOrderScreen.setInvisible();
                break;
            case WAIT_NEW_ORDER:
                finalConsumerMode = Mode.WAIT_NEW_ORDER;
                if(addItemsScreen != null){
                    addItemsScreen.setVisible();
                    addItemsScreen.setAddItemsMode(AddItemsScreen.Mode.WAIT_NEW_ORDER);
                }
                if(finalizeOrderScreen != null) finalizeOrderScreen.setInvisible();
                break;
            case ENDING_ORDER:
                finalConsumerMode = Mode.ENDING_ORDER;
                if(addItemsScreen != null) addItemsScreen.setInvisible();
                if(finalizeOrderScreen != null) finalizeOrderScreen.showEndOrder();
                break;
        }
    }


    @Override
    public void onClientsListReturn(ArrayList<Client> clientsList) {
        getFinalConsumerDetails(clientsList);
    }

    @Override
    public void onEstablishmentsListReturn(ArrayList<Establishment> estabs) {
        initFinalConsumerDetails(estabs.get(0));
    }

    @Override
    public void onDefaultEstablishmentReturn(Establishment establishment) {
    }

    @Override
    public void onEstablishmentParamsReturn(EstabParamsDefault estabParamsDefault) {
        this.finalConsumerParamsDefault = estabParamsDefault;
        addItemsScreen.selectPriceTable(estabParamsDefault.getTprvenId());
    }

    /*****WEB SERVICE CALLBACKS***/

    @Override
    public void OnWebServiceCompanyParamsDefaultReturn(CompanyParameters params) {
        //adiciona na cache
        mServerDataCacheBinder.addCompanyParams(codSelectedCompany, params);
        initCompanyParams(params);
    }

    @Override
    public void failedOnRetrieveCompanyParamsDefault() {

        ShowMessage.alertDialog2(getActivity(), R.string.makeorder_failongetcompanyparams,
                new DialogInterface.OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        switch (which) {
                            case DialogInterface.BUTTON_NEGATIVE:
                                getActivity().finish();
                                break;
                            case DialogInterface.BUTTON_POSITIVE:
                                ServerConnection.getCompanyParamsDefault(String.valueOf(codSelectedCompany), FinalConsumerFragment.this);
                                break;
                        }
                    }
                });
    }

    @Override
    public void failedOnRetrivePriceTables() {

    }

    @Override
    public void OnWebServicePriceTablesReturn(ArrayList<PriceTable> priceTables) {
        //adiciona na cache
        mServerDataCacheBinder.addCompanyPriceTable(codSelectedCompany, priceTables);
        addItemsScreen.setPriceTableList(priceTables);
    }


    @Override
    public void failedGetUnitsOfMeasurement() {

    }

    @Override
    public void OnWebServiceUnitsOfMeasurementReturn(ArrayList<UnitOfMeasurement> unitOfMeasurementArrayList) {
        mServerDataCacheBinder.addUnitsOfMeasurement(codSelectedCompany, unitOfMeasurementArrayList);
        addItemsScreen.setUnitsOfMeasurement(unitOfMeasurementArrayList);
    }

    /****************************/



    /*****Getters and Setters*****/
    @Override
    public void setSelectedCompany(int codSelectedCompany) {
        if(codSelectedCompany != this.codSelectedCompany){
            this.codSelectedCompany = codSelectedCompany;
            if(clientManager != null) clientManager.setCodSelectedCompany(codSelectedCompany);
            if(addItemsScreen != null) addItemsScreen.setCodSelectedCompany(codSelectedCompany);
            setFinalConsumerMode(Mode.WAIT_NEW_ORDER);
        }
    }
    @Override
    public int getSelectedCompany() {
        return codSelectedCompany;
    }
    /*****************************/

    /***Finalizar pedido dialog***/

    public void stopOrderRemovedInSaveScreen(String orderId) {
        if(currentOrder != null){
            if(currentOrder.getId().equals(orderId)) {
                orderFinalized(null);
            }
        }
    }

    @Override
    public void finalizeOrder(Order order) {
        currentOrder = order;
        orderManager.setOrder(order);
        orderManager.sendOrderAndFinalize();
    }

    @Override
    public void saveOrder(Order order) {
        currentOrder = order;
        orderManager.setOrder(order);
        orderManager.sendOrderToServer();
    }

    @Override
    public void backButtonClick(Order order) {
        currentOrder = order;
        addItemsScreen.setAddedItems(itemsToSend);
        setFinalConsumerMode(Mode.MAKE_ORDER);
        addItemsScreen.setVisible();
        finalizeOrderScreen.setInvisible();
    }

    @Override
    public void addItemsScreenBackButtonClick() {
    }

    @Override
    public void newOrderButtonClick() {

    }

    @Override
	public void refresh() {
		// TODO Auto-generated method stub
	}


    /*****************************/

}
